package cn.lili.modules.order.cart.render.impl;

import cn.lili.common.enums.PromotionTypeEnum;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.common.utils.SpringContextUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.modules.distribution.client.DistributionClient;
import cn.lili.modules.distribution.entity.dos.Distribution;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.cart.entity.enums.RenderStepEnums;
import cn.lili.modules.order.cart.entity.vo.CartSkuVO;
import cn.lili.modules.order.cart.entity.vo.CartVO;
import cn.lili.modules.order.cart.render.CartRenderStep;
import cn.lili.modules.order.order.entity.dto.PriceDetailDTO;
import cn.lili.modules.order.order.service.TradeService;
import cn.lili.modules.system.client.SettingClient;
import cn.lili.modules.system.entity.enums.SettingEnum;
import com.alibaba.fastjson.JSONObject;
import com.api.PayApi;
import com.pojos.UserRes;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 购物车渲染，将购物车中的各个商品，拆分到每个商家，形成购物车VO
 *
 * @author Chopper
 * @see CartVO
 */
@Service
@Slf4j
public class CartPriceRender implements CartRenderStep {

    @Autowired
    private TradeService tradeService;

    Map<SettingEnum, com.alibaba.fastjson.JSONObject> settings = new HashMap<>();
    private final Logger logger = LoggerFactory.getLogger(CartPriceRender.class);
    @Resource
    private DistributionClient distributionClient;


    @Override
    public RenderStepEnums step() {
        return RenderStepEnums.CART_PRICE;
    }

    @Override
    public void render(TradeDTO tradeDTO) {

        // 计算绿色积分总和
        log.info("tradeDTO.getCartList() == {}",tradeDTO.getCartList());
        log.info("dict.getCartList() == {}",tradeDTO.getCartList().stream().distinct().collect(Collectors.toList()));

        recountGreenAndFmoneyScore(tradeDTO);

        // 计算商品加个
        log.info("begin  ==  tradeDTO.recountPrice().getFlowPrice() == {}", tradeDTO.getPriceDetailDTO().getFlowPrice());
        recountPrice(tradeDTO);
        log.info("end  === tradeDTO.recountPrice().getFlowPrice() == {}", tradeDTO.getPriceDetailDTO().getFlowPrice());
        //价格过滤 在购物车商品失效时，需要对价格进行初始化操作
        initPriceDTO(tradeDTO);

        log.info("tradeDTO.initPriceDTO().getFlowPrice() == {}", tradeDTO.getPriceDetailDTO().getFlowPrice());

        //构造cartVO
        buildCartPrice(tradeDTO);
        log.info("tradeDTO.buildCartPrice().getFlowPrice() == {}", tradeDTO.getPriceDetailDTO().getFlowPrice());
        buildTradePrice(tradeDTO);
        log.info("tradeDTO.buildTradePrice().getFlowPrice() == {}", tradeDTO.getPriceDetailDTO().getFlowPrice());

        //buildFmoney(tradeDTO);

        //tradeService.beforeCheck(tradeDTO);
        logger.info("计算运费后 {}", tradeDTO.getPriceDetailDTO());
        logger.info("运费计算结果 {}", tradeDTO.getPriceDetailDTO().getFreightPrice());
    }

    /**
     * 设置绿色积分和F分
     * @param tradeDTO
     */
    private void recountGreenAndFmoneyScore(TradeDTO tradeDTO){
        for (CartVO cartVO : tradeDTO.getCartList()) {
            for (CartSkuVO cartSkuVO : cartVO.getSkuList()) {
                if ((null != cartSkuVO.getPromotionTypeEnum() && PromotionTypeEnum.PINTUAN.name().equals(cartSkuVO.getPromotionTypeEnum().name()))
                        || (null != cartSkuVO.getGoodsSku().getPromotionFlag() && cartSkuVO.getGoodsSku().getPromotionFlag())) {
                    cartSkuVO.getPriceDetailDTO().setGreenScore(0D);
                }else {
                    cartSkuVO.getPriceDetailDTO().setGreenScore(CurrencyUtil.mul(cartSkuVO.getGreenScore(), cartSkuVO.getNum()));
                }
            }
        }
        /*tradeDTO.getCartList().forEach(cartVO -> cartVO.getSkuList().forEach(cartSkuVO ->
                cartSkuVO.getPriceDetailDTO().setGreenScore(CurrencyUtil.mul(cartSkuVO.getGreenScore(), cartSkuVO.getNum()))));*/
        tradeDTO.getCartList().forEach(cartVO -> cartVO.getSkuList().forEach(cartSkuVO ->
                cartSkuVO.getPriceDetailDTO().setMaxFmoney(CurrencyUtil.mul(cartSkuVO.getMaxfNumber(), cartSkuVO.getNum()))));
    }

    /**
     * 计算价格
     *
     * @param tradeDTO
     */
    private void recountPrice(TradeDTO tradeDTO) {
        log.info("tradeDTO.getCartList() == {}", JSONObject.toJSONString(tradeDTO.getCartList()));
        initSetting();
        tradeDTO.getCartList().forEach(cartVO -> cartVO.getSkuList().forEach(cartSkuVO -> {
            log.info("=====recountPrice======{}", cartSkuVO.getPromotionTypeEnum());
            //计算减免金额
            Distribution currentDistribution = distributionClient.getDistributionPass(UserContext.getCurrentId());
            if(currentDistribution!=null && null == cartSkuVO.getPromotionTypeEnum()){
                //比例
                double number = CurrencyUtil.div(settings.get(SettingEnum.GREEN_GOODS).getDouble("lowerProportion"),100);
                //优惠金额
                //这里增加逻辑,如果开启了一级分销的商品,则不进入以下判断
                if (StringUtils.isEmpty(tradeDTO.getDistributionId()) && (cartSkuVO.getGoodsSku() == null || cartSkuVO.getGoodsSku().getIsLevelDistribution() == null || !cartSkuVO.getGoodsSku().getIsLevelDistribution())) {
                    cartSkuVO.getPriceDetailDTO().setOmitGreenScore(CurrencyUtil.mul(CurrencyUtil.mul(cartSkuVO.getGreenScore(),number), cartSkuVO.getNum()));
                }
            }
            cartSkuVO.getPriceDetailDTO().recount();
        }));
    }

    /**
     * 特殊情况下对购物车金额进行护理
     *
     * @param tradeDTO
     */
    private void initPriceDTO(TradeDTO tradeDTO) {
        tradeDTO.getCartList().forEach(cartVO -> cartVO.setPriceDetailDTO(new PriceDetailDTO()));
        tradeDTO.setPriceDetailDTO(new PriceDetailDTO());
    }

    /**
     * 购物车价格
     *
     * @param tradeDTO 购物车展示信息
     */
    void buildCartPrice(TradeDTO tradeDTO) {
        //购物车列表
        List<CartVO> cartVOS = tradeDTO.getCartList();

        cartVOS.forEach(cartVO -> {

            cartVO.getPriceDetailDTO().accumulationPriceDTO(
                    cartVO.getCheckedSkuList().stream().filter(CartSkuVO::getChecked)
                            .map(CartSkuVO::getPriceDetailDTO).collect(Collectors.toList())
            );
            List<Integer> skuNum = cartVO.getSkuList().stream().filter(CartSkuVO::getChecked)
                    .map(CartSkuVO::getNum).toList();
            for (Integer num : skuNum) {
                cartVO.addGoodsNum(num);
            }
        });
    }


    /**
     * 初始化购物车
     *
     * @param tradeDTO 购物车展示信息
     */
    void buildTradePrice(TradeDTO tradeDTO) {
        tradeDTO.getPriceDetailDTO().accumulationPriceDTO(
                tradeDTO.getCartList().stream().map(CartVO::getPriceDetailDTO).toList());
    }

    /**
     * 计算F分抵扣
     * @param tradeDTO
     */
    void buildFmoney(TradeDTO tradeDTO){
        AuthUser currentUser = Objects.requireNonNull(UserContext.getCurrentUser());

        if(tradeDTO.getPriceDetailDTO().getMaxFmoney() != 0) {
            try {
                PayApi payApi = SpringContextUtil.getBean(PayApi.class);

                UserRes res = payApi.getUserMoney(currentUser.getOpenId());

                if(tradeDTO.isUseFmoney()) {
                    if(tradeDTO.getPriceDetailDTO().getMaxFmoney() > CurrencyUtil.div(new BigDecimal(res.getBalance()).doubleValue(), 100)) {
                        tradeDTO.setFmoney(CurrencyUtil.div(new BigDecimal(res.getBalance()).doubleValue(), 100));
                    }else {
                        tradeDTO.setFmoney(tradeDTO.getPriceDetailDTO().getMaxFmoney());
                    }
                }else {
                    tradeDTO.setFmoney(0D);
                }
            }catch(Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void initSetting(){
        SettingClient settingClient = SpringContextUtil.getBean(SettingClient.class);

        com.alibaba.fastjson.JSONObject greenGoodsSetting = com.alibaba.fastjson.JSONObject.parseObject(settingClient.get(SettingEnum.GREEN_GOODS.name()).getSettingValue());
        com.alibaba.fastjson.JSONObject goodsSetting = com.alibaba.fastjson.JSONObject.parseObject(settingClient.get(SettingEnum.NOT_GREEN_GOODS.name()).getSettingValue());

        settings.put(SettingEnum.GREEN_GOODS, greenGoodsSetting);
        settings.put(SettingEnum.NOT_GREEN_GOODS, goodsSetting);
    }
}
